<template>
  <div class="tabs-container">
    <el-tabs
      v-model="activePath"
      class="tabs"
      type="card"
      closable
      @tab-click="clickTabs"
      @tab-remove="closeTabs"
    >
      <el-tab-pane
        v-for="item in tabsStore.list"
        :key="item.path"
        :label="item.title"
        :name="item.path"
      ></el-tab-pane>
    </el-tabs>
    <div class="Tabs-close-box">
      <el-dropdown @command="handleTags">
        <el-button size="small" type="primary" plain>
          标签选项
          <el-icon class="el-icon--right">
            <ArrowDown />
          </el-icon>
        </el-button>
        <template #dropdown>
          <el-dropdown-menu size="small">
            <el-dropdown-item command="other">关闭其他</el-dropdown-item>
            <el-dropdown-item command="current">关闭当前</el-dropdown-item>
            <el-dropdown-item command="all">关闭所有</el-dropdown-item>
          </el-dropdown-menu>
        </template>
      </el-dropdown>
    </div>
  </div>
</template>

<script setup lang="ts">
  import { ref, watch } from 'vue'
  import { useTabsStore } from '@/store/tabs'
  import { onBeforeRouteUpdate, RouteLocationNormalized, useRoute, useRouter } from 'vue-router'
  import { ArrowDown } from '@element-plus/icons-vue'
  import type { TabPaneName, TabsPaneContext } from 'element-plus'

  const route = useRoute()
  const router = useRouter()
  const activePath = ref(route.fullPath)
  const tabsStore = useTabsStore()
  // 设置标签
  const setTags = (route: RouteLocationNormalized) => {
    const name = route.name ? String(route.name) : ''
    const title = typeof route.meta.title === 'string' ? route.meta.title : ''
    const keepAlive = !!route.meta.keepAlive
    const path = route.fullPath

    const isExist = tabsStore.list.some(item => item.name === name)
    if (isExist) {
      tabsStore.setPath(name, path)
    } else {
      tabsStore.setTabsItem({
        name,
        title,
        keepAlive,
        path,
      })
    }
  }
  setTags(route)
  onBeforeRouteUpdate(to => {
    setTags(to)
  })

  // 关闭全部标签
  const closeAll = () => {
    tabsStore.clearTabs()
    router.push('/')
  }
  // 关闭其他标签
  const closeOther = () => {
    const curItem = tabsStore.list.filter(item => {
      return item.path === route.fullPath
    })
    tabsStore.closeTabsOther(curItem)
  }
  const handleTags = (command: string) => {
    switch (command) {
      case 'current':
        // 关闭当前页面的标签页
        tabsStore.closeCurrentTag({
          $router: router,
          $route: route,
        })
        break
      case 'all':
        closeAll()
        break

      case 'other':
        closeOther()
        break
    }
  }

  // 切换标签页
  const clickTabs = (pane: TabsPaneContext) => {
    // pane.paneName 就是 el-tab-pane 的 name 属性
    if (pane.paneName) {
      router.push(String(pane.paneName))
    }
  }
  // 关闭标签页
  const closeTabs = (name: TabPaneName) => {
    // name 可能是 string 或 number
    const path = String(name)
    const index = tabsStore.list.findIndex(item => item.path === path)
    tabsStore.delTabsItem(index)
    const item = tabsStore.list[index] || tabsStore.list[index - 1]
    router.push(item ? item.path : '/')
  }

  watch(
    () => route.fullPath,
    (newVal, _oldVal) => {
      activePath.value = newVal
    }
  )
</script>

<style>
  .tabs-container {
    position: relative;
    overflow: hidden;
    background: #fff;
    padding: 2px 120px 0 0;
  }

  .tabs {
    /*noinspection CssUnusedSymbol*/

    .el-tabs__header {
      margin-bottom: 0;
    }

    /*noinspection CssUnusedSymbol*/

    .el-tabs__nav {
      height: 28px;
    }

    /*noinspection CssUnusedSymbol*/

    .el-tabs__nav-next,
    .el-tabs__nav-prev {
      line-height: 32px;
    }

    /*noinspection CssUnusedSymbol*/

    .el-tabs {
      --el-tabs-header-height: 28px;
    }
  }

  .Tabs-close-box {
    position: absolute;
    right: 0;
    top: 0;
    box-sizing: border-box;
    padding-top: 1px;
    text-align: center;
    width: 110px;
    height: 30px;
    background: #fff;
    box-shadow: -3px 0 15px 3px rgba(0, 0, 0, 0.1);
    z-index: 10;
  }
</style>
